<template>
  <div class="main-container">
    <el-form ref="taskForm" :model="taskData" :rules="rules">
      <!-- 基本配置 -->
    <div class="data-show">
      <!-- 标题 -->
      <div class="data-actions">
        <h3>基本配置</h3>
      </div>
      <!-- 内容区 -->
      <div class="data-table">
        <!-- 通用布局行 -->
        <div class="common-row row-between">
          <!-- 配置项 - 任务名称 -->
          <div class="common-item item-3">
            <label class="condition-label">任务名称</label>
            <el-form-item class="condition-input" prop="name">
              <el-input type="text" :disabled="taskData.done" placeholder="请输入消息名称" v-model="taskData.name" />
            </el-form-item>
          </div>
          <!-- 配置项 - 平台 -->
          <div class="common-item item-3">
            <label class="condition-label">社交平台</label>
            <el-form-item class="condition-input" prop="system">
              <el-select :disabled="taskData.done" v-model="taskData.system" clearable placeholder="请选择平台">
                <el-option v-for="(item, index) in systems" :key="index" :label="item.label" :value="item.value"></el-option>
              </el-select>
            </el-form-item>
          </div>
          <!-- 配置项 - 类型 -->
          <div class="common-item item-3">
            <label class="condition-label">用户</label>
            <el-form-item class="condition-input" prop="userID">
              <el-input type="text" :disabled="taskData.done" placeholder="请输入用户" v-model="taskData.userID" />
            </el-form-item>
          </div>
        </div>
        <!-- 通用布局行 -->
        <div class="common-row">
          <div class="common-item item-10">
            <label class="condition-label">任务描述</label>
            <el-form-item class="condition-input" prop="description">
              <el-input :disabled="taskData.done" v-model="taskData.description" maxlength="100" type="textarea" show-word-limit :rows="4" resize="none" placeholder="请输入任务描述" />
            </el-form-item>
          </div>
        </div>
      </div>
    </div>
    <!-- 任务上传 -->
    <div class="data-show">
      <!-- 标题 -->
      <div class="data-actions">
        <h3>消息上传</h3>
      </div>
      <!-- 内容区 -->
      <div class="data-table">
        <!-- 通用布局行 - 任务prompt -->
        <div class="common-row">
          <div class="common-item item-10" :class="{'item-upload': uploadObj.messageTextFilePath.showFileList}">
            <el-tooltip content="切换上传方式" placement="top">
              <label class="condition-label condition-label-change" @click="changeUploadType('messageTextFilePath', taskData)">消息文件</label>
            </el-tooltip>
            <el-form-item class="condition-input" prop="messageTextFilePath">
              <el-upload
                v-if="uploadObj.messageTextFilePath.isUploadType"
                class="upload"
                :ref="uploadObj.uploadRef('messageTextFilePath')"
                :disabled="taskData.done"
                drag
                :action="uploadObj.uploadUrl"
                :limit="1"
                :show-file-list="uploadObj.messageTextFilePath.showFileList"
                :before-upload="uploadObj.beforeUpload('messageTextFilePath')"
                :on-success="uploadObj.onSuccess('messageTextFilePath', taskForm)"
                :on-progress="uploadObj.onProgress('messageTextFilePath')"
                :on-error="uploadObj.onError('messageTextFilePath')"
                :on-remove="uploadObj.onRemove('messageTextFilePath')"
              >
                <transition name="upload">
                  <div class="upload-empty" v-if="!taskData.messageTextFilePath">
                    <i class="iconfont icon-icon_update upload-icon"></i>
                    <p class="upload-des">拖拽文件至此或点击上传</p>
                  </div>
                  <div class="upload-content" v-else>
                    <i class="iconfont icon-daimawenjian-mian upload-icon"></i>
                    <p class="upload-des">{{ uploadObj.messageTextFilePath.fileName }}</p>
                  </div>
                </transition>
              </el-upload>
              <el-input :disabled="taskData.done" v-else type="textarea" @input="clearData('messageTextFilePath')" @change="createBlobTxt($event, 'messageTextFilePath', taskForm)" v-model="uploadObj.messageTextFilePath.text" maxlength="255" show-word-limit :rows="5" resize="none" placeholder="请输入文本" />
            </el-form-item>
          </div>
        </div>
      </div>
    </div>
    <transition name="upload">
      <!-- 底部的按钮 -->
      <div class="btn-groups" v-if="!taskData.done">
        <button type="button" class="btn btn-normal" @click="handleCancel">取消</button>
        <button type="button" :disabled="taskData.createFlag" class="btn" @click="handleCreate">上传</button>
      </div>
      <el-row :gutter="20" v-else>
        <el-col :span="12">
          <div class="data-show">
            <!-- 标题 -->
            <div class="data-actions data-title-between">
              <h3>签名信息</h3>
            </div>
            <div class="data-table data-table-scroll">
              <p class="text-container">
                {{ changeJSON(taskData.signature) }}
              </p>
            </div>
          </div>
        </el-col>
        <el-col :span="12">
          <div class="data-show">
            <!-- 标题 -->
            <div class="data-actions data-title-between">
              <h3>载密文本</h3>
            </div>
            <div class="data-table data-table-scroll">
              <p class="text-container">
                {{ changeJSON(taskData.stegoText) }}
              </p>
            </div>
          </div>
        </el-col>
      </el-row>
    </transition>
    </el-form>
  </div>
</template>
<script setup>
import useAppStore from '@/stores/app';
import { ref, computed, onActivated } from 'vue';
import { API } from '@/utils/status.js';
import { useRouter, useRoute } from 'vue-router';
import { ElMessage } from 'element-plus';
import * as rule from '@/utils/rules';
import * as uploadApi from '@/api/file';
import * as request from '@/api/steganography';

const router = useRouter();
const route = useRoute();

const systems = API.steganography.systems;
const defaultTaskData = {
  id: null,
  done: false,
  createFlag: false,
  name: '',
  description: '',
  system: null,
  userID: null,
  messageTextFilePath: null,
  // 结果 - 签名密文
  signature: null,
  stegoText: null
};
const defaultUpload = {
  isUploadType: true,
  text: '',
  dom: null,
  showFileList: false,
  fileName: '',
  uploading: false
}

// ============> data <============
const appStore = useAppStore();
const taskForm = ref(null);
// 绑定表单对象
const taskData = ref({
  id: null,
  done: false,
  createFlag: false,
  name: '',
  description: '',
  system: null,
  userID: null,
  messageTextFilePath: null,
  // 结果 - 签名密文
  signature: null,
  stegoText: null
});
// 上传控制对象
const uploadObj = ref({
  uploadUrl: `${import.meta.env.VITE_FILE_BASE_API}${uploadApi.uploadUrl}`,
  uploadRef(key){
    return function (dom){
      if (dom){
        uploadObj.value[key].dom = dom;
      }
    }
  },
  beforeUpload(key){
    return function (file){
      if (uploadObj.value[key].uploading){
        ElMessage.warning('当前有文件正在上传，请稍后重试');
        return false;
      }
      let extension = file.size < API.upload.commonLimit;
      if (!extension) {
        ElMessage.warning(`上传文件超过大小限制，文件须小于${API.upload.commonLimit / (1024 * 1024)}M`)
      }
      let fileType = file.name.substring(file.name.lastIndexOf('.') + 1);
      extension = fileType == 'txt' ? true : false;
      if (!extension) {
        ElMessage.warning('上传文件须为.txt文件!');
      }
      uploadObj.value[key].fileName = extension ? file.name : '';
      uploadObj.value[key].showFileList = true;
      return extension;
    }
  },
  onSuccess(key, form){
    return function (e){
      uploadObj.value[key].dom.clearFiles();
      uploadObj.value[key].showFileList = false;
      uploadObj.value[key].uploading = false;
      console.log('上传res')
      console.log(e)
      if (e.code === API.code.SUCCESS) { 
        ElMessage.success('上传成功');
        taskData.value[key] = e.data.path;
      } else {
        let msg = e.msg || e.message || '上传失败，请稍后重试或联系管理员';
        ElMessage({
          type: 'error',
          duration: 1500,
          message: msg
        });
      }
      form.validateField([key])
    }
  },
  onProgress(key){
    return function (e){
      uploadObj.value[key].showFileList = true;
      uploadObj.value[key].uploading = true;
    }
  },
  onError(key){
    return function (e){
      console.log(e)
      let message = e.msg || e.message || '上传失败，请稍后重试或联系管理员'
      ElMessage({
        type: 'error',
        duration: 1500,
        message
      });
      uploadObj.value[key].showFileList = false;
      uploadObj.value[key].uploading = false;
      uploadObj.value[key].dom.clearFiles();
      uploadObj.value[key].fileName = '';
    }
  },
  onRemove(key){
    return function (e){
      uploadObj.value[key].showFileList = false;
      uploadObj.value[key].uploading = false;
      uploadObj.value[key].dom.clearFiles();
      uploadObj.value[key].fileName = '';
    }
  },
  messageTextFilePath: {
    isUploadType: true,
    text: '',
    dom: null,
    showFileList: false,
    fileName: '',
    uploading: false
  }
});
// 表单验证规则
const rules = {
  name: rule.createRequired('任务名称不能为空'),
  userID: rule.createRequired('用户不能为空'),
  // messageTextFilePath: rule.createRequired('请上传消息文件')
  messageTextFilePath: rule.createTextUpload(uploadObj.value, 'messageTextFilePath', '消息文件不能为空')
};
const changeJSON = computed(() => {
  return function (jsonString){
    return jsonString ? window.decodeURIComponent(JSON.parse(jsonString)) : '';
  }
})

// ============> hooks <============
// todo 这里要在onActived中初始化整个页面的状态对象，如果创建中会一直无法重置
onActivated(() => {
  let { id, isCreate, reenter } = route.query;
  if (reenter || (id !== undefined && id == taskData.value.id)){
    return;
  }
  if (isCreate){
    init();
    return;
  }
  reInit();
});

// ========> methods <========
function init(){
  taskData.value = Object.assign({}, defaultTaskData);
  uploadObj.value.messageTextFilePath = Object.assign({}, defaultUpload);
}
function reInit(){
  let { id } = route.query;
  init();
  request.getTaskDetailById({id})
    .then(res => {
      let result = res;
      result.infoData = JSON.parse(res.infoData);
      console.log(result);
      taskData.value.id = result.id;
      taskData.value.name = result.name;
      taskData.value.description = result.description;
      taskData.value.createFlag = false;
      taskData.value.userID = result.infoData.userID;
      if (result.status > 0 && result.infoData.signature !== null && result.infoData.stegoText!== undefined){
        taskData.value.done = true;
        taskData.value.signature = result.infoData.signature;
        taskData.value.stegoText = result.infoData.stegoText;
        taskData.value.messageTextFilePath = result.infoData.messageTextFilePath;
        uploadObj.value.messageTextFilePath.fileName = 'message.txt';
      }
    })
}
function changeUploadType(key, data){
  if (data.done){
    return;
  }
  uploadObj.value[key].isUploadType = !uploadObj.value[key].isUploadType;
  uploadObj.value[key].text = '';
  uploadObj.value[key].showFileList = false;
  uploadObj.value[key].fileName = '';
  uploadObj.value[key].uploading = false;
  data[key] = null;
}
function clearData(key){
  taskData.value[key] = '';
}
// 上传项文本输入事件
function createBlobTxt(e, key, form){
  if (!e){
    taskData.value[key] = '';
    ElMessage.success('上传成功');
    return;
  }
  const blob = new Blob([e], { type: 'text/plain' });
  const txt = new File([blob], 'file.txt', { type: 'text/plain' });
  let formData = new FormData();
  formData.append('file', txt);
  uploadApi.upload(formData)
    .then(res => {
      console.log('上传res')
      ElMessage.success('上传成功');
      taskData.value[key] = res.path;
      console.log(taskData.value)
      form.validateField([key])
    })
    .catch(err => {
      console.log(err)
      let msg = err.msg || err.message || '上传失败，请稍后重试或联系管理员';
      ElMessage.error(msg);
      form.validateField([key])
    })
}
// 点击创建按钮
function handleCreate(){
  if (taskData.value.createFlag){
    ElMessage.warning('当前正在进行签名、嵌入，请稍后');
    return;
  }
  taskForm.value.validate(valid => {
    if (valid){
      taskData.value.createFlag = true;
      appStore.openLoading('签名、嵌入中...');
      request.appFourServerSign({
        name: taskData.value.name,
        description: taskData.value.description,
        moduleType: API.steganography.moduleType.APPFOUR,
        infoData: {
          userID: taskData.value.userID,
          messageTextFilePath: taskData.value.messageTextFilePath
        }
      })
        .then(res => {
          console.log(res)
          taskData.value.createFlag = false;
          appStore.closeLoading();
          if (res && res.infoData && res.infoData.signature && res.infoData.stegoText){
            ElMessage.success('签名、嵌入成功');
            taskData.value.done = true;
            taskData.value.signature = res.infoData.signature;
            taskData.value.stegoText = res.infoData.stegoText;
          } else {
            ElMessage.error('签名、嵌入失败，请稍后重试或联系管理员');
          }
        })
        .catch(err => {
          console.log(err);
          taskData.value.createFlag = false;
          appStore.closeLoading();
        })
    } else {
      ElMessage.warning('提交信息有误，请核对');
    }
  })
}
// 点击取消按钮
function handleCancel(){
  router.back();
}
</script>
<style lang='scss' scoped>
@import '@/assets/styles/mixin.scss';
.row-between {
  justify-content: space-between;
}
.item-3 {
  width: 30%
}
.item-10 {
  width: 100%;
  height: auto;
  padding: 20px 0;
  .condition-label {
    width: 15%;
  }
  .condition-input {
    width: 80%;
  }
}
.item-10-spe {
  width: 100%;
  .condition-label {
    width: 15%;
  }
  .condition-input {
    width: 80%;
  }
  &::v-deep .el-form-item__content {
    align-items: center!important;
  }
}
.item-5 {
  width: 49%;
  height: auto;
  padding: 50px 0 60px 0;
}
.item-upload {
  padding-bottom: 50px;
}
.upload {
  width: 100%;
  min-height: 120px;
  height: 120px;
  &::v-deep .el-upload {
    @include wh-100;
    // height: 100%!important;
    .el-upload-dragger {
      @include wh-100;
      border-color: var(--color-main);
      padding: 0;
      .upload-empty {
        @include wh-100;
        @include flex-all-center;
        flex-direction: column;
        .upload-icon {
          font-size: 30px;
          color: var(--color-gray-10);
        }
        .upload-des {
          color: var(--color-gray-10);
        }
      }
      .upload-content {
        @include wh-100;
        @include flex-all-center;
        flex-direction: column;
        .upload-icon {
          font-size: 30px;
          color: var(--color-main);
        }
        .upload-des {
          color: var(--color-main);
        }
      }
    }
  }
}
.btn-groups {
  margin-top: 20px;
  text-align: center;
  .btn {
    margin: 0 20px;
  }
}
.condition-label-change {
  cursor: pointer;
}
.condition-label-change:hover {
  color: var(--color-primary);
}
.data-table-scroll {
  max-height: 220px;
  height: auto;
  overflow-y: auto;
  @include scrollBar;
  .file-image {
    width: 100%;
    height: 190px;
    background-color: var(--color-gray-2);
    border: 1px solid var(--color-main-border);
    border-radius: 6px;
  }
}
</style>